package com.teamwork.module03.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.teamwork.common.util.FileUtils;
import com.teamwork.common.util.RegexUtil;
import com.teamwork.module03.mapper.UserMapper;

import com.teamwork.module03.service.UserIconService;
import com.teamwork.module03.service.UserService;
import com.teamwork.common.entity.common.User;
import com.teamwork.common.entity.common.UserIcon;
import com.teamwork.common.entity.common.requestentity.ReqUserBody;
import com.teamwork.common.entity.common.responeentity.ResUserBody;
import com.teamwork.common.entity.module03.Article;
import com.teamwork.common.entity.module03.Author;
import com.teamwork.common.result.Result;
import com.teamwork.module03.service.ArticleService;
import com.teamwork.module03.service.AuthorService;
import com.teamwork.module03.service.CommentService;
import com.teamwork.module03.service.ReplyService;
import com.teamwork.module03.service.file.UploadService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Objects;

@Service
@Slf4j
@Transactional
public class UserServiceImpl  extends ServiceImpl<UserMapper, User> implements UserService {

    @Resource
    private ArticleService articleService;
    @Resource
    private CommentService commentService;
    @Resource
    private ReplyService replyService;
    @Resource
    private AuthorService authorService;
    @Resource
    private UserIconService userIconService;
    @Resource
    private UploadService uploadService;

    
    @Override
    public Result pageUser() {

        User user = this.getById(1);

        return Result.success(user);
    }

    /**
     * 根据用户名查询用户
     * @param username
     */
    @Override
    public User getByUsername(String username) {
        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(User::getUsername,username);
        User one = this.getOne(wrapper);
        if(one!=null){
            return one;
        }
        return null;
    }

    /**
     * 根据邮箱查询用户
     * @param email
     * @return
     */
    @Override
    public User getByEmail(String email) {
        LambdaQueryWrapper<User> wrapper =new LambdaQueryWrapper<>();
        wrapper.eq(User::getEmail,email);
        User one = this.getOne(wrapper);
        if(one!=null) return one;
        return null;
    }

    /**
     * 按条件分页查询用户信息
     * @param
     * @param
     * @param reqUserBody 请求实体
     * @return Result
     */
    @Override
    public Result pageSelect(ReqUserBody reqUserBody) {

        LambdaQueryWrapper<User> wrapper =new LambdaQueryWrapper<>();
        Page<User> userPage = new Page<>(reqUserBody.getPage(),reqUserBody.getSize());

        Integer status = reqUserBody.getStatus();
        Integer role  = reqUserBody.getRole();
        String username = reqUserBody.getUsername();
        String nickname = reqUserBody.getNickname();
        String email = reqUserBody.getEmail();

        //*********************************************************************************************
        //当这些都为空是，则为正常分页查询
        if(status==2 && role==4 && username==null && nickname==null && email==null){
          //  System.err.println("1.正常查询");
            wrapper.orderByDesc(User::getCreatetime);
            this.page(userPage,wrapper);
           // System.out.println(userPage.getRecords())
            //*********************************************************************************************
        }else if(status==2 && role==4 && username!=null && nickname==null && email==null){
           // System.err.println("2.用户名查询");
            wrapper.like(User::getUsername,username).orderByDesc(User::getCreatetime);
            this.page(userPage,wrapper);
        }else if(status==2 && role==4 && username==null && nickname!=null && email==null){
           /// System.err.println("3.昵称查询");
            wrapper.like(User::getNickname,nickname).orderByDesc(User::getCreatetime);
            this.page(userPage,wrapper);
        }else if(status==2 && role==4 && username==null && nickname==null && email!=null){
           // System.err.println("4.邮箱查询");
            wrapper.like(User::getEmail,email).orderByDesc(User::getCreatetime);
            this.page(userPage,wrapper);
        }
        else if( status!=2 && role==4 && username==null && nickname==null && email==null ){
          //System.err.println("5.转态查询");
            //根据转态查询
            wrapper.eq(User::getStatus,status).orderByDesc(User::getCreatetime);
            this.page(userPage,wrapper);
            //*********************************************************************************************
        }else if(role!=4 && status==2 && username==null && nickname==null && email==null  ){
            //System.err.println("6.角色查询");
            //根据角色一般查询
            wrapper.eq(User::getRole,role).orderByDesc(User::getCreatetime);
            this.page(userPage,wrapper);
            //*********************************************************************************************
        }else if(status!=2 && role!=4  && username==null && nickname==null && email==null ){
          //System.out.println("7.状态和角色查询");
            //根据转态和角色查询
            wrapper.eq(User::getStatus,status).eq(User::getRole,role).orderByDesc(User::getCreatetime);
            this.page(userPage,wrapper);
        }else if(status!=2 && role!=4 && username!=null && nickname==null && email==null){
            //System.err.println("8.状态，角色，用户名查询");
            //状态 角色 用户名
             wrapper.eq(User::getStatus,status).eq(User::getRole,role).like(User::getUsername,username);
             this.page(userPage,wrapper);
            //*********************************************************************************************
        }else if(status!=2 && role!=4 && username==null && nickname!=null && email==null){
            //System.err.println("9.状态，角色，昵称查询");
            //状态 角色 昵称
            wrapper.eq(User::getStatus,status).eq(User::getRole,role).like(User::getNickname,nickname);
            this.page(userPage,wrapper);
            //*********************************************************************************************
        }else if(status!=2 && role!=4 && username==null && nickname==null && email!=null){
            //System.err.println("10.状态，角色，邮箱查询");
            //状态 角色 邮箱
            wrapper.eq(User::getStatus,status).eq(User::getRole,role).like(User::getEmail,email);
            this.page(userPage,wrapper);
        }else if(status == 2 && role!=4 && username!=null && nickname==null && email==null){
          //  System.err.println("11.角色，用户名查询");
            //根据角色 用户名查询
            wrapper.eq(User::getRole,role).like(User::getUsername,username).orderByDesc(User::getCreatetime);
            this.page(userPage,wrapper);
        }else if(status == 2 && role!=4 && username==null &&nickname!=null && email==null){
          //  System.err.println("12.，角色，昵称查询");
            wrapper.eq(User::getRole,role).like(User::getNickname,nickname).orderByDesc(User::getCreatetime);
            this.page(userPage,wrapper);
        } else if (status == 2 && role != 4 && username == null && nickname == null && email != null) {
           // System.err.println("13.角色，邮箱查询");
            wrapper.eq(User::getRole,role).like(User::getEmail,email).orderByDesc(User::getCreatetime);
            this.page(userPage,wrapper);
        }

        //*********************************************************************************************
        List<User> users = userPage.getRecords();

        List<ResUserBody> resUserBodyList = new ArrayList<>();
        for (User user : users) {
          // user.setPassword(null);
            //密码解密
            UserIcon icon = userIconService.getByUserId(Math.toIntExact(user.getId()));
            String iconpath = icon.getIcon();
            System.out.println(iconpath);
            ResUserBody resUserBody = new ResUserBody(user,iconpath);
            resUserBodyList.add(resUserBody);
        }

        Page<ResUserBody> resPage = new Page<>();

        BeanUtils.copyProperties(userPage,resPage,"records");


        resPage.setRecords(resUserBodyList);

        return Result.success(resPage);
    }

    /**
     * 删除单个用户
     * @param id 用户id
     * @return 返回Result
     */
    @Override
    public Result deleteById(Integer id) {
         //先查询该用户是否为作者
        Author author = authorService.getByUserId(id);
        if(author!=null){
            //该用户是作者
            //查询该用户是否发过文章
            List<Article> articles = articleService.getArtListByAuId(Math.toIntExact(author.getId()));
            if(articles.size()!=0){
                //说明该作者发表过文章
                //把这些文章删除了
              articleService.deleteByAuId(Math.toIntExact(author.getId()));
            }
            //在吧作者信息删除了
            this.authorService.deleteByUserId(id);
        }
        //该用户不为作者，删除该用户发表过的评论和回复
           commentService.deleteByUserId(id);
         //删除该用户发表的所有回复
           replyService.deleteByUserId(id);

        //该用户不为作者，删除用户图片和用户信息
         userIconService.deleteByUserId(id);
        //最后删除用户信息
        boolean b = this.removeById(id);
        if(b) log.info("删除一条用户id :{} 的记录",id);
       // else log.error("删除一条用户id :{} 的记录出错！！！",id);


        return Result.success("删除用户成功!该用户发表的文章，评论都删除");
    }

    /**
     * 批量删除用户
     * @param ids
     * @return
     */
    @Override
    public Result deleteBuchByIds(Integer[] ids) {
        for (Integer id : ids) {
            this.deleteById(id);
        }
        return Result.success("删除成功");
    }

    /**
     * 根据用户id查询个人主页信息（头像，昵称，关注，粉丝，文章数量）
     * @param userid
     * @return
     */
    @Override
    public Result getMineByUid(Integer userid) {
        //先查询用户头像
        UserIcon userIcon = userIconService.getByUserId(userid);
        String icon = userIcon.getIcon();
        //在查询用户的关注，粉丝，文章数量
        Author author = authorService.getByUserId(userid);

        String nickname = author.getNickname();
        Integer cares = author.getCares();
        Integer fensi = author.getFensi();
        Integer articles = author.getArticles();

        HashMap<String,Object> map =new HashMap<>();
        map.put("icon",icon);
        map.put("nickname",nickname);
        map.put("cares",cares);
        map.put("fensi",fensi);
        map.put("articles",articles);

        return Result.success(map);
    }

    /**
     * 根据用户id获取用户信息
     * @param userid
     * @return
     */
    @Override
    public Result getUserInfo(Integer userid) {

        User user = this.getById(userid);

        UserIcon icon = userIconService.getByUserId(userid);
        String usericon = icon.getIcon();

        HashMap<String, Object> map = new HashMap<>();
        map.put("user",user);
        map.put("icon",usericon);

        return Result.success(map);
    }

    /**
     * 修改用户的信息
     * @param user
     * @return
     */
    @Override
    @Transactional
    public Result editUserInfo(User user) {
        Long userid = user.getId();
        String nickname = user.getNickname();
        String phone = user.getPhone();
        String email = user.getEmail();

        if(nickname.equals("")||phone.equals("")||email.equals("")){
            return Result.failure("信息不能为空！");
        }
        //根据手机号，邮箱查询是否已经被人注册过了
        LambdaQueryWrapper<User> wrapper =new LambdaQueryWrapper<>();

        User one = this.getOne(wrapper.eq(User::getPhone,phone));

        if(one!=null && !Objects.equals(one.getId(), user.getId())){
            //该手机号是除了该用户之外的人用过
            return Result.failure("该手机号已经被其他人使用");
        }

        User one2 = this.getOne(wrapper.eq(User::getEmail, email));
        if(one2!=null && !Objects.equals(one2.getId(), user.getId())){
            //该邮箱被除了该用户之外的人使用
            return Result.failure("该邮箱已经被其他人使用");
        }
        //都没问题，可以修改
        User mysqluser = this.getById(userid);

        mysqluser.setNickname(nickname);
        mysqluser.setPhone(phone);
        mysqluser.setEmail(email);
        boolean b = this.updateById(mysqluser);

        //修改作者表里的昵称
        Author author = authorService.getByUserId(Math.toIntExact(userid));
        author.setNickname(nickname);
        boolean b1 = authorService.updateById(author);

        if(!b||!b1){
            log.error("用户id:{} 修改个人信息失败！！！",userid);
            return Result.failure("修改个人信息失败！,后台错误！");
        }
        return Result.success("修改个人信息成功!");
    }

    /**
     * 管理员修改用户
     * @param userid
     * @param img
     * @param username
     * @param nickname
     * @param email
     * @param phone
     * @return
     */
    @Override
    public Result updateUser(Integer userid, MultipartFile img, String username,
                             String password,String nickname, String email, String phone) throws IOException {
        //先查询该用户在不在
        User user = this.getById(userid);
        if(user==null) return Result.failure("该用户不存在！");
        //匹配格式
        if(!username.matches(RegexUtil.REGEX_USERNAME)){
            return Result.failure("用户名不符合格式！");
        } else if (!password.matches(RegexUtil.REGEX_PASSWORD)) {
            return Result.failure("密码格式不正确");
        } else if(!email.matches(RegexUtil.REGEX_EMAIL)){
            log.info("email:{}",email);
            return Result.failure("邮箱不符合格式");
        }else if(!phone.matches(RegexUtil.REGEX_PHONE)){
            return Result.failure("手机号格式不正确");
        }
        //这些都没问题了，再查看该用户名是否已经存在且只有一次
        LambdaQueryWrapper<User> wrapper=new LambdaQueryWrapper<>();
        wrapper.eq(User::getUsername,username);
        User one = this.getOne(wrapper);
        if(one!=null && !one.getId().toString().equals(userid.toString())){
            return Result.failure("该用户名已经被其他用户使用！");
        }
        //再查看该邮箱是否已经存在
        User one1 = this.getOne(wrapper.eq(User::getEmail, email));

        if(one1!=null && !one1.getId().toString().equals(userid.toString())){
            return Result.failure("该邮箱已使用！");
        }
        User one2 = this.getOne(wrapper.eq(User::getPhone, phone));
        if(one2!=null && !one2.getId().toString().equals(userid.toString())){
            return Result.failure("该手机号已使用！");
        }
        //都没问题了，可以修改
        user.setUsername(username);
        //密码加密
        user.setPassword(new BCryptPasswordEncoder().encode(password));
        user.setNickname(nickname);
        user.setEmail(email);
        user.setPhone(phone);
        boolean b = this.updateById(user);
        if(!b){
            log.error("修改用户信息失败，用户id:{}",userid);
            return Result.failure("修改失败！");
        }
        if(img!=null){
            //再修改用户头像
            Result result = uploadService.uploadUserIcon(img, userid);
            if(result.getCode()!=200){
                return Result.failure("用户头像上传失败！");
            }
        }



        return Result.success("修改用户信息成功！");


    }

    /**
     * 管理员添加用户
     * @param userid
     * @param img
     * @param username
     * @param nickname
     * @param password
     * @param email
     * @param phone
     * @param role
     * @return
     */
    @Override
    @Transactional
    public Result insertUser(Integer userid, MultipartFile img, String username, String nickname, String password, String email, String phone, Integer role) throws IOException {
       //先判断该用户是不是管理员在操作，
        if (this.getById(userid).getRole()!=3) {
            return Result.failure("该操作不是管理员发起，没有权限添加用户");
        }
        //匹配格式
        if(!username.matches(RegexUtil.REGEX_USERNAME)){
            return Result.failure("用户名不符合格式！");
        } else if (!password.matches(RegexUtil.REGEX_PASSWORD)) {
            return Result.failure("密码格式不正确");
        } else if(!email.matches(RegexUtil.REGEX_EMAIL)){
            log.info("email:{}",email);
            return Result.failure("邮箱不符合格式");
        }else if(!phone.matches(RegexUtil.REGEX_PHONE)){
            return Result.failure("手机号格式不正确");
        }
        //这些都没问题了，再查看该用户名是否已经存在且只有一次
        LambdaQueryWrapper<User> wrapper=new LambdaQueryWrapper<>();
        wrapper.eq(User::getUsername,username);
        User one = this.getOne(wrapper);
        if(one!=null){
            return Result.failure("该用户名已经被其他用户使用！");
        }
        //再查看该邮箱是否已经存在
        User one1 = this.getOne(wrapper.eq(User::getEmail, email));

        if(one1!=null){
            return Result.failure("该邮箱已使用！");
        }
        User one2 = this.getOne(wrapper.eq(User::getPhone, phone));
        if(one2!=null){
            return Result.failure("该手机号已使用！");
        }
        //都没问题了，可以添加
        User user = new User();
        user.setUsername(username);
        //密码加密
        user.setPassword(new BCryptPasswordEncoder().encode(password));
        user.setNickname(nickname);
        user.setEmail(email);
        user.setPhone(phone);
        user.setRole(role);
        //判断该用户是一般用户还是审核或管理
            //审核或管理员
            boolean b = this.save(user);
            if(!b){
                log.error("管理员新增用户失败!!!");
                return Result.failure("添加用户失败！后台错误！");
            }
            if(role==1) {
                //一般用户
               //添加作者表信息
                Author author=new Author();
                author.setUserId(user.getId());
                author.setCares(0);
                author.setUsername(username);
                author.setFensi(0);
                author.setArticles(0);
                author.setNickname(nickname);
                //插入作者表
                boolean b1 = authorService.save(author);
                if(!b1) {
                    log.error("管理员添加一般用户插入作者表记录失败！");
                    return Result.failure("添加失败，后台插入作者表错误");
                }
            }
            //在插入图片
           if(img!=null) {
               System.out.println("img不为空");
               //再修改用户头像
               Result result = uploadService.uploadUserIcon(img, Math.toIntExact(user.getId()));
               if (result.getCode() != 200) {
                   return Result.failure("用户头像上传失败！");
               }
           }else{

                System.out.println("img为空");
                //图片为空，则默认给设置一张图片
                uploadService.setMorenUserIcon(user.getId());
            }

           //都没问题了，则返回正确结果
        return Result.success("添加用户信息成功!");
    }


}
